{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Alibaba Cloud Container Service for Kubernetes (ACK) Deep MNIST Example\n",
    "In this example we will deploy a tensorflow MNIST model in the Alibaba Cloud Container Service for Kubernetes.\n",
    "\n",
    "This tutorial will break down in the following sections:\n",
    "\n",
    "1) Train a tensorflow model to predict mnist locally\n",
    "\n",
    "2) Containerise the tensorflow model with our docker utility\n",
    "\n",
    "3) Test model locally with docker\n",
    "\n",
    "4) Set-up and configure Alibaba Cloud environment\n",
    "\n",
    "5) Deploy your model and visualise requests\n",
    "\n",
    "#### Let's get started! 🚀🔥\n",
    "\n",
    "## Dependencies:\n",
    "\n",
    "* Helm v2.13.1+\n",
    "* kubectl v1.14+\n",
    "* Python 3.6+\n",
    "* Python DEV requirements\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1) Train a tensorflow model to predict mnist locally\n",
    "We will load the mnist images, together with their labels, and then train a tensorflow model to predict the right labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-1-559b63ab8b48>:2: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting MNIST_data/train-images-idx3-ubyte.gz\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting MNIST_data/train-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n",
      "Extracting MNIST_data/t10k-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data/t10k-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "WARNING:tensorflow:From /home/alejandro/miniconda3/envs/reddit-classification/lib/python3.7/site-packages/tensorflow/python/util/tf_should_use.py:193: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.\n",
      "Instructions for updating:\n",
      "Use `tf.global_variables_initializer` instead.\n",
      "0.9191\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "mnist = input_data.read_data_sets(\"MNIST_data/\", one_hot = True)\n",
    "import tensorflow as tf\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    \n",
    "    x = tf.placeholder(tf.float32, [None,784], name=\"x\")\n",
    "\n",
    "    W = tf.Variable(tf.zeros([784,10]))\n",
    "    b = tf.Variable(tf.zeros([10]))\n",
    "\n",
    "    y = tf.nn.softmax(tf.matmul(x,W) + b, name=\"y\")\n",
    "\n",
    "    y_ = tf.placeholder(tf.float32, [None, 10])\n",
    "\n",
    "    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))\n",
    "\n",
    "    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)\n",
    "\n",
    "    init = tf.initialize_all_variables()\n",
    "\n",
    "    sess = tf.Session()\n",
    "    sess.run(init)\n",
    "\n",
    "    for i in range(1000):\n",
    "        batch_xs, batch_ys = mnist.train.next_batch(100)\n",
    "        sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})\n",
    "\n",
    "    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))\n",
    "    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
    "    print(sess.run(accuracy, feed_dict = {x: mnist.test.images, y_:mnist.test.labels}))\n",
    "\n",
    "    saver = tf.train.Saver()\n",
    "\n",
    "    saver.save(sess, \"model/deep_mnist_model\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2) Containerise the tensorflow model with our docker utility"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a wrapper file that exposes the functionality through a `predict` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting DeepMnist.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile DeepMnist.py\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "\n",
    "class DeepMnist(object):\n",
    "    def __init__(self):\n",
    "        self.class_names = [\"class:{}\".format(str(i)) for i in range(10)]\n",
    "        self.sess = tf.Session()\n",
    "        saver = tf.train.import_meta_graph(\"model/deep_mnist_model.meta\")\n",
    "        saver.restore(self.sess,tf.train.latest_checkpoint(\"./model/\"))\n",
    "\n",
    "        graph = tf.get_default_graph()\n",
    "        self.x = graph.get_tensor_by_name(\"x:0\")\n",
    "        self.y = graph.get_tensor_by_name(\"y:0\")\n",
    "\n",
    "    def predict(self,X,feature_names):\n",
    "        predictions = self.sess.run(self.y,feed_dict={self.x:X})\n",
    "        return predictions.astype(np.float64)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define the dependencies for the wrapper in the requirements.txt:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting requirements.txt\n"
     ]
    }
   ],
   "source": [
    "%%writefile requirements.txt\n",
    "tensorflow>=1.12.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You need to make sure that you have added the .s2i/environment configuration file in this folder with the following content:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mkdir: cannot create directory ‘.s2i’: File exists\r\n"
     ]
    }
   ],
   "source": [
    "!mkdir .s2i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting .s2i/environment\n"
     ]
    }
   ],
   "source": [
    "%%writefile .s2i/environment\n",
    "MODEL_NAME=DeepMnist\n",
    "API_TYPE=REST\n",
    "SERVICE_TYPE=MODEL\n",
    "PERSISTENCE=0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can build a docker image named \"deep-mnist\" with the tag 0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---> Installing application source...\n",
      "---> Installing dependencies ...\n",
      "Looking in links: /whl\n",
      "Requirement already satisfied: tensorflow>=1.12.0 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (1.13.1)\n",
      "Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.0.7)\n",
      "Requirement already satisfied: absl-py>=0.1.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (0.7.1)\n",
      "Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (0.2.2)\n",
      "Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.0.9)\n",
      "Requirement already satisfied: tensorboard<1.14.0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.13.1)\n",
      "Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (0.7.1)\n",
      "Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (0.32.2)\n",
      "Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (3.7.1)\n",
      "Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.12.0)\n",
      "Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.20.1)\n",
      "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.1.0)\n",
      "Requirement already satisfied: numpy>=1.13.3 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.16.3)\n",
      "Requirement already satisfied: tensorflow-estimator<1.14.0rc0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 1)) (1.13.0)\n",
      "Requirement already satisfied: h5py in /usr/local/lib/python3.6/site-packages (from keras-applications>=1.0.6->tensorflow>=1.12.0->-r requirements.txt (line 1)) (2.9.0)\n",
      "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 1)) (3.1)\n",
      "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 1)) (0.15.4)\n",
      "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/site-packages (from protobuf>=3.6.1->tensorflow>=1.12.0->-r requirements.txt (line 1)) (40.6.2)\n",
      "Requirement already satisfied: mock>=2.0.0 in /usr/local/lib/python3.6/site-packages (from tensorflow-estimator<1.14.0rc0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 1)) (3.0.5)\n",
      "Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "You are using pip version 18.1, however version 19.1.1 is available.\n",
      "You should consider upgrading via the 'pip install --upgrade pip' command.\n",
      "Build completed successfully\n"
     ]
    }
   ],
   "source": [
    "!s2i build . seldonio/seldon-core-s2i-python36:0.13 deep-mnist:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3) Test model locally with docker\n",
    "We first run the docker image we just created as a container called \"mnist_predictor\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9087047e368ac8f285e1f742704b4c0c7bceac7d29ee90b3b0a6ef2d61ebd15c\r\n"
     ]
    }
   ],
   "source": [
    "!docker run --name \"mnist_predictor\" -d --rm -p 5000:5000 deep-mnist:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Send some random features that conform to the contract"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Expected label:  7.0 . One hot encoding:  [[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "# This is the variable that was initialised at the beginning of the file\n",
    "i = [0]\n",
    "x = mnist.test.images[i]\n",
    "y = mnist.test.labels[i]\n",
    "plt.imshow(x.reshape((28, 28)), cmap='gray')\n",
    "plt.show()\n",
    "print(\"Expected label: \", np.sum(range(0,10) * y), \". One hot encoding: \", y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LABEL 0:\t 0.0064 %\n",
      "LABEL 1:\t 0.0000 %\n",
      "LABEL 2:\t 0.0155 %\n",
      "LABEL 3:\t 0.2862 %\n",
      "LABEL 4:\t 0.0003 %\n",
      "LABEL 5:\t 0.0027 %\n",
      "LABEL 6:\t 0.0000 %\n",
      "LABEL 7:\t 99.6643 %\n",
      "LABEL 8:\t 0.0020 %\n",
      "LABEL 9:\t 0.0227 %\n"
     ]
    }
   ],
   "source": [
    "from seldon_core.seldon_client import SeldonClient\n",
    "import math\n",
    "import numpy as np\n",
    "\n",
    "# We now test the REST endpoint expecting the same result\n",
    "endpoint = \"0.0.0.0:5000\"\n",
    "batch = x\n",
    "payload_type = \"ndarray\"\n",
    "\n",
    "sc = SeldonClient(microservice_endpoint=endpoint)\n",
    "\n",
    "# We use the microservice, instead of the \"predict\" function\n",
    "client_prediction = sc.microservice(\n",
    "    data=batch,\n",
    "    method=\"predict\",\n",
    "    payload_type=payload_type,\n",
    "    names=[\"tfidf\"])\n",
    "\n",
    "for proba, label in zip(client_prediction.response.data.ndarray.values[0].list_value.ListFields()[0][1], range(0,10)):\n",
    "    print(f\"LABEL {label}:\\t {proba.number_value*100:6.4f} %\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mnist_predictor\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm mnist_predictor --force"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4) Set-up and configure Alibaba Cloud environment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 create a managed kubernetes cluster \n",
    "We need to first create a cluster in Alibaba Cloud - you should follow the following instructions (make sure you expose the cluster with an elastic IP by checking the tickbox): https://www.alibabacloud.com/help/doc-detail/95108.htm\n",
    "\n",
    "You should follow up the instructions but the finished cluster should look as follows:\n",
    "\n",
    "![](images/k8s-dashboard-2.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 Copy the kubectl configuration to access the cluster"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once you have the cluster created, you will be able to use your local kubectl by copying the configuration details on the overview page, and copy it to your ~/.kube/config"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 Create an Alibaba Container Registry to push the image\n",
    "Finally we need to create a container registry repository by following this guide: https://www.alibabacloud.com/blog/up-and-running-with-alibaba-cloud-container-registry_593765"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.4 Install Seldon Core and all Dependencies\n",
    "\n",
    "Now we can run all the commands you will need to install Seldon Core. Make sure you have all the dependencies listed at the top, including helm, kubectl, etc."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### We first install seldon core, we need to install HELM to manage our packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "clusterrolebinding.rbac.authorization.k8s.io/kube-system-cluster-admin created\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Error from server (AlreadyExists): serviceaccounts \"tiller\" already exists\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl create serviceaccount tiller --namespace kube-system"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "clusterrolebinding.rbac.authorization.k8s.io/tiller-role-binding created\r\n"
     ]
    }
   ],
   "source": [
    "!kubectl apply -f tiller-role-binding.yaml"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Once that is set-up we can update and install Tiller"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hang tight while we grab the latest from your chart repositories...\n",
      "...Skip local chart repository\n",
      "...Successfully got an update from the \"argo\" chart repository\n",
      "...Successfully got an update from the \"akomljen-charts\" chart repository\n",
      "...Successfully got an update from the \"incubator\" chart repository\n",
      "...Successfully got an update from the \"elastic\" chart repository\n",
      "...Successfully got an update from the \"stable\" chart repository\n",
      "Update Complete. ⎈ Happy Helming!⎈ \n"
     ]
    }
   ],
   "source": [
    "!helm repo update"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "$HELM_HOME has been configured at /home/alejandro/.helm.\n",
      "Warning: Tiller is already installed in the cluster.\n",
      "(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)\n",
      "Happy Helming!\n"
     ]
    }
   ],
   "source": [
    "!helm init --service-account tiller"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "deployment \"tiller-deploy\" successfully rolled out\r\n"
     ]
    }
   ],
   "source": [
    "# Wait until Tiller finishes\n",
    "!kubectl rollout status deploy/tiller-deploy -n kube-system"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Now we can install SELDON. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME:   seldon-core-operator\n",
      "LAST DEPLOYED: Sat Jul 13 16:54:46 2019\n",
      "NAMESPACE: default\n",
      "STATUS: DEPLOYED\n",
      "\n",
      "RESOURCES:\n",
      "==> v1/ClusterRole\n",
      "NAME                          AGE\n",
      "seldon-operator-manager-role  2s\n",
      "\n",
      "==> v1/ClusterRoleBinding\n",
      "NAME                                 AGE\n",
      "seldon-operator-manager-rolebinding  2s\n",
      "\n",
      "==> v1/Pod(related)\n",
      "NAME                                  READY  STATUS             RESTARTS  AGE\n",
      "seldon-operator-controller-manager-0  0/1    ContainerCreating  0         2s\n",
      "\n",
      "==> v1/Secret\n",
      "NAME                                   TYPE    DATA  AGE\n",
      "seldon-operator-webhook-server-secret  Opaque  0     2s\n",
      "\n",
      "==> v1/Service\n",
      "NAME                                        TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE\n",
      "seldon-operator-controller-manager-service  ClusterIP  172.21.7.141  <none>       443/TCP  2s\n",
      "\n",
      "==> v1/ServiceAccount\n",
      "NAME                  SECRETS  AGE\n",
      "seldon-core-operator  1        2s\n",
      "\n",
      "==> v1/StatefulSet\n",
      "NAME                                READY  AGE\n",
      "seldon-operator-controller-manager  0/1    2s\n",
      "\n",
      "==> v1beta1/CustomResourceDefinition\n",
      "NAME                                         AGE\n",
      "seldondeployments.machinelearning.seldon.io  2s\n",
      "\n",
      "\n",
      "NOTES:\n",
      "NOTES: TODO\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!helm install seldon-core-operator --name seldon-core-operator --repo https://storage.googleapis.com/seldon-charts --set usageMetrics.enabled=true\n",
    "!kubectl rollout status deploy/seldon-controller-manager "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Now we set-up the ingress so we can access it\n",
    "In alicloud this will actually create an Elastic Load Balancer that will enable us to access all our deployed Seldon Components"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME:   ambassador\n",
      "LAST DEPLOYED: Sat Jul 13 16:55:11 2019\n",
      "NAMESPACE: default\n",
      "STATUS: DEPLOYED\n",
      "\n",
      "RESOURCES:\n",
      "==> v1/Deployment\n",
      "NAME        READY  UP-TO-DATE  AVAILABLE  AGE\n",
      "ambassador  0/3    3           0          1s\n",
      "\n",
      "==> v1/Pod(related)\n",
      "NAME                         READY  STATUS             RESTARTS  AGE\n",
      "ambassador-67f5b657dd-fxpl9  0/1    ContainerCreating  0         1s\n",
      "ambassador-67f5b657dd-ntzgx  0/1    ContainerCreating  0         1s\n",
      "ambassador-67f5b657dd-wnlp7  0/1    ContainerCreating  0         1s\n",
      "\n",
      "==> v1/Service\n",
      "NAME               TYPE          CLUSTER-IP    EXTERNAL-IP  PORT(S)                     AGE\n",
      "ambassador         LoadBalancer  172.21.6.30   <pending>    80:31872/TCP,443:32589/TCP  1s\n",
      "ambassador-admins  ClusterIP     172.21.14.77  <none>       8877/TCP                    1s\n",
      "\n",
      "==> v1/ServiceAccount\n",
      "NAME        SECRETS  AGE\n",
      "ambassador  1        1s\n",
      "\n",
      "==> v1beta1/ClusterRole\n",
      "NAME        AGE\n",
      "ambassador  1s\n",
      "\n",
      "==> v1beta1/ClusterRoleBinding\n",
      "NAME        AGE\n",
      "ambassador  1s\n",
      "\n",
      "==> v1beta1/CustomResourceDefinition\n",
      "NAME                                          AGE\n",
      "authservices.getambassador.io                 1s\n",
      "consulresolvers.getambassador.io              1s\n",
      "kubernetesendpointresolvers.getambassador.io  1s\n",
      "kubernetesserviceresolvers.getambassador.io   1s\n",
      "mappings.getambassador.io                     1s\n",
      "modules.getambassador.io                      1s\n",
      "ratelimitservices.getambassador.io            1s\n",
      "tcpmappings.getambassador.io                  1s\n",
      "tlscontexts.getambassador.io                  1s\n",
      "tracingservices.getambassador.io              1s\n",
      "\n",
      "\n",
      "NOTES:\n",
      "Congratuations! You've successfully installed Ambassador.\n",
      "\n",
      "For help, visit our Slack at https://d6e.co/slack or view the documentation online at https://www.getambassador.io.\n",
      "\n",
      "To get the IP address of Ambassador, run the following commands:\n",
      "NOTE: It may take a few minutes for the LoadBalancer IP to be available.\n",
      "     You can watch the status of by running 'kubectl get svc -w  --namespace default ambassador'\n",
      "\n",
      "  On GKE/Azure:\n",
      "  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].ip}')\n",
      "\n",
      "  On AWS:\n",
      "  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n",
      "\n",
      "  echo http://$SERVICE_IP:\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!helm install stable/ambassador --name ambassador --set crds.keep=false\n",
    "!kubectl rollout status deployment.apps/ambassador"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fianlly we install the Seldon Analytics Package"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!helm install seldon-core-analytics --repo https://storage.googleapis.com/seldon-charts --name seldon-core-analytics\n",
    "!kubectl rollout status deployment.apps/grafana-prom-deployment\n",
    "!kubectl patch svc grafana-prom --type='json' -p '[{\"op\":\"replace\",\"path\":\"/spec/type\",\"value\":\"LoadBalancer\"}]'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.5 Push docker image\n",
    "We'll now make sure the image is accessible within the Kubernetes cluster by pushing it to the repo that we created in step 4.3. This should look as follows in your dashboard:\n",
    "\n",
    "![](images/k8s-dashboard-1.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### To push the image we first tag it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "!docker tag deep-mnist:0.1 registry-intl.eu-west-1.aliyuncs.com/seldonalibaba/deep-mnist:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### And then we push it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The push refers to repository [registry-intl.eu-west-1.aliyuncs.com/seldonalibaba/deep-mnist]\n",
      "\n",
      "\u001b[1B358e90f3: Preparing \n",
      "\u001b[1Be4a983d1: Preparing \n",
      "\u001b[1B74b2c556: Preparing \n",
      "\u001b[1B9472b523: Preparing \n",
      "\u001b[1Ba2a7ea60: Preparing \n",
      "\u001b[1Beddb328a: Preparing \n",
      "\u001b[1B1393f8e7: Preparing \n",
      "\u001b[1B67d6e30e: Preparing \n",
      "\u001b[1Bf19da2c9: Preparing \n",
      "\u001b[1B9ec591c4: Preparing \n",
      "\u001b[1B32b1ff99: Preparing \n",
      "\u001b[1B64f96dbc: Preparing \n",
      "\u001b[1Be6d76fd9: Preparing \n",
      "\u001b[1B11a84ad4: Preparing \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[4B64f96dbc: Pushing  105.6MB/141.8MB\u001b[14A\u001b[1K\u001b[KPushing     512B/4.43kB\u001b[12A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  548.9kB/648.8MB\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[12A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[9A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[8A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[8A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[10A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[KPushing  7.426MB/16.85MB\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[15A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[6A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  57.75MB/65.26MB\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[7A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[KPushing  22.51MB/556.5MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[3A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[11A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  45.06MB/648.8MB\u001b[2A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[2A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[KPushing   66.6MB/141.8MB\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  82.16MB/556.5MB\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[KPushing  96.63MB/556.5MB\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13B4b2c556: Pushing    377MB/648.8MB\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  72.91MB/648.8MB\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  158.4MB/556.5MB\u001b[5A\u001b[1K\u001b[K\u001b[4A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[KPushing  103.4MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[1A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  197.5MB/556.5MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  266.3MB/556.5MB\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  176.6MB/648.8MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  268.1MB/648.8MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  269.8MB/648.8MB\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  280.8MB/648.8MB\u001b[5A\u001b[1K\u001b[KPushing  404.4MB/556.5MB\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  422.9MB/556.5MB\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[KPushing  345.7MB/648.8MB\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[13B4b2c556: Pushed   659.3MB/648.8MB\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[KPushing  467.2MB/648.8MB\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[5A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K\u001b[13A\u001b[1K\u001b[K0.1: digest: sha256:13ab55662f0e8479bb51d998a8014f7f059a73422295bcd400f62615d36355dc size: 3482\n"
     ]
    }
   ],
   "source": [
    "!docker push registry-intl.eu-west-1.aliyuncs.com/seldonalibaba/deep-mnist:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5 - Deploy your model and visualise requests\n",
    "\n",
    "**IMPORTANT: Make sure you replace the URL for your repo in the format of:**\n",
    "* registry-intl.**[REPO]**.aliyuncs.com/**[REGISTRY]**/**[REPO]**:0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting deep_mnist_deployment.yaml\n"
     ]
    }
   ],
   "source": [
    "%%writefile deep_mnist_deployment.yaml\n",
    "---\n",
    "apiVersion: machinelearning.seldon.io/v1alpha2\n",
    "kind: SeldonDeployment\n",
    "metadata:\n",
    "  labels:\n",
    "    app: seldon\n",
    "  name: deep-mnist\n",
    "spec:\n",
    "  annotations:\n",
    "    project_name: Tensorflow MNIST\n",
    "    deployment_version: v1\n",
    "  name: deep-mnist\n",
    "  oauth_key: oauth-key\n",
    "  oauth_secret: oauth-secret\n",
    "  predictors:\n",
    "  - componentSpecs:\n",
    "    - spec:\n",
    "        containers:\n",
    "        # REPLACE_FOR_IMAGE_AND_TAG\n",
    "        - image: registry-intl.eu-west-1.aliyuncs.com/seldonalibaba/deep-mnist:0.1 \n",
    "          imagePullPolicy: IfNotPresent\n",
    "          name: classifier\n",
    "          resources:\n",
    "            requests:\n",
    "              memory: 1Mi\n",
    "        terminationGracePeriodSeconds: 20\n",
    "    graph:\n",
    "      children: []\n",
    "      name: classifier\n",
    "      endpoint:\n",
    "        type: REST\n",
    "      type: MODEL\n",
    "    name: single-model\n",
    "    replicas: 1\n",
    "    annotations:\n",
    "      predictor_version: v1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Run the deployment in your cluster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "kubectl apply -f deep_mnist_deployment.yaml"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### And let's check that it's been created."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!kubectl get pods"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Test the model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll use a random example from our dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Expected label:  7.0 . One hot encoding:  [[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "# This is the variable that was initialised at the beginning of the file\n",
    "i = [0]\n",
    "x = mnist.test.images[i]\n",
    "y = mnist.test.labels[i]\n",
    "plt.imshow(x.reshape((28, 28)), cmap='gray')\n",
    "plt.show()\n",
    "print(\"Expected label: \", np.sum(range(0,10) * y), \". One hot encoding: \", y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### First we need to find the URL that we'll use \n",
    "You need to add it to the script in the next block"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8.208.23.117"
     ]
    }
   ],
   "source": [
    "!kubectl get svc ambassador -o jsonpath='{.status.loadBalancer.ingress[0].ip}'  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now add the URL above to send our request:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "meta {\n",
      "  puid: \"krop281g4e1mrsgf60m7ilh1fc\"\n",
      "  requestPath {\n",
      "    key: \"classifier\"\n",
      "    value: \"registry-intl.eu-west-1.aliyuncs.com/seldonalibaba/deep-mnist:0.1\"\n",
      "  }\n",
      "}\n",
      "data {\n",
      "  names: \"class:0\"\n",
      "  names: \"class:1\"\n",
      "  names: \"class:2\"\n",
      "  names: \"class:3\"\n",
      "  names: \"class:4\"\n",
      "  names: \"class:5\"\n",
      "  names: \"class:6\"\n",
      "  names: \"class:7\"\n",
      "  names: \"class:8\"\n",
      "  names: \"class:9\"\n",
      "  ndarray {\n",
      "    values {\n",
      "      list_value {\n",
      "        values {\n",
      "          number_value: 4.4009637349518016e-05\n",
      "        }\n",
      "        values {\n",
      "          number_value: 6.321029477618367e-09\n",
      "        }\n",
      "        values {\n",
      "          number_value: 0.0001286377664655447\n",
      "        }\n",
      "        values {\n",
      "          number_value: 0.0030034701339900494\n",
      "        }\n",
      "        values {\n",
      "          number_value: 3.061768893530825e-06\n",
      "        }\n",
      "        values {\n",
      "          number_value: 1.882280412246473e-05\n",
      "        }\n",
      "        values {\n",
      "          number_value: 1.8899024567531342e-08\n",
      "        }\n",
      "        values {\n",
      "          number_value: 0.9959828853607178\n",
      "        }\n",
      "        values {\n",
      "          number_value: 2.070009031740483e-05\n",
      "        }\n",
      "        values {\n",
      "          number_value: 0.0007983553223311901\n",
      "        }\n",
      "      }\n",
      "    }\n",
      "  }\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from seldon_core.seldon_client import SeldonClient\n",
    "import math\n",
    "import numpy as np\n",
    "import subprocess\n",
    "\n",
    "# Add the URL you found above, here:\n",
    "HOST = \"8.208.23.117\"\n",
    "\n",
    "\n",
    "port = \"80\" # Make sure you use the port above\n",
    "batch = x\n",
    "payload_type = \"ndarray\"\n",
    "\n",
    "sc = SeldonClient(\n",
    "    gateway=\"ambassador\", \n",
    "    gateway_endpoint=HOST + \":\" + port,\n",
    "    namespace=\"default\",\n",
    "    oauth_key=\"oauth-key\", \n",
    "    oauth_secret=\"oauth-secret\")\n",
    "\n",
    "client_prediction = sc.predict(\n",
    "    data=batch, \n",
    "    deployment_name=\"deep-mnist\",\n",
    "    names=[\"text\"],\n",
    "    payload_type=payload_type)\n",
    "\n",
    "print(client_prediction.response)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Let's see the predictions for each label\n",
    "It seems that it correctly predicted the number 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LABEL 0:\t 0.0044 %\n",
      "LABEL 1:\t 0.0000 %\n",
      "LABEL 2:\t 0.0129 %\n",
      "LABEL 3:\t 0.3003 %\n",
      "LABEL 4:\t 0.0003 %\n",
      "LABEL 5:\t 0.0019 %\n",
      "LABEL 6:\t 0.0000 %\n",
      "LABEL 7:\t 99.5983 %\n",
      "LABEL 8:\t 0.0021 %\n",
      "LABEL 9:\t 0.0798 %\n"
     ]
    }
   ],
   "source": [
    "for proba, label in zip(client_prediction.response.data.ndarray.values[0].list_value.ListFields()[0][1], range(0,10)):\n",
    "    print(f\"LABEL {label}:\\t {proba.number_value*100:6.4f} %\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Finally let's visualise the metrics that seldon provides out of the box\n",
    "For this we can access the URL with the command below, it will request an admin and password which by default are set to the following:\n",
    "* Username: admin\n",
    "* Password: admin\n",
    "\n",
    "**You will be able to access it at http://[URL]/d/ejAHFXIWz/prediction-analytics?orgId=1**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8.208.25.68"
     ]
    }
   ],
   "source": [
    "!kubectl get svc grafana-prom -o jsonpath='{.status.loadBalancer.ingress[0].ip}'  "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The metrics include requests per second, as well as latency. You are able to add your own custom metrics, and try out other more complex deployments by following furher guides at https://docs.seldon.io/projects/seldon-core/en/latest/workflow/README.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](images/graf.jpg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
